home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
hardware
/
386id
/
386id2.asm
< prev
next >
Wrap
Assembly Source File
|
1994-02-23
|
17KB
|
712 lines
title ID386PPI -- PPI Subroutines to 386ID
page 58,122
name ID386PPI
COMMENT| Module Specifications
Copyright: (C) Copyright 1987-94 Qualitas, Inc.
Segmentation: Group PGROUP:
Program segment CODE, word-aligned, public, class 'prog'
Data segment DATA, dword-aligned, public, class 'data'
Original code by: Bob Smith, November, 1987.
|
.386
.xlist
include MISC.INC
.list
PGROUP group CODE,DATA
DATA segment use16 dword public 'data' ; Start DATA segment
assume ds:PGROUP
extrn LCL_FLAG:word
include ID3_LCL.INC
extrn XMSDRV_VEC:dword
@XMS_LCLENA equ 05h ; Local Enable A20
@XMS_LCLDIS equ 06h ; Local Disable A20
ACTA20_STR struc
ACTA20_MC dw ?
ACTA20_ISA dw ?
ACTA20_XMS dw ?
ACTA20_STR ends
public ACTA20_ENA
ACTA20_ENA ACTA20_STR <PGROUP:A20ENA_MC,PGROUP:A20ENA_ISA,PGROUP:A20ENA_XMS>
public ACTA20_DIS
ACTA20_DIS ACTA20_STR <PGROUP:A20DIS_MC,PGROUP:A20DIS_ISA,PGROUP:A20DIS_XMS>
DATA ends ; End DATA segment
CODE segment use16 word public 'prog' ; Start CODE segment
assume cs:PGROUP
NPPROC A20ENA_MC -- A20 Enable for MC Systems
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 enable for Micro Channel Systems
On entry:
AL = @PS2_A port value
On exit:
AL = (updated to enable A20)
|
or al,mask $PS2_GATE ; Enable A20
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
A20ENA_MC endp ; End A20ENA_MC procedure
NPPROC A20ENA_ISA -- A20 Enable for ISA
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 enable for ISA
On entry:
AL = output port byte
On exit:
AL = (updated to enable A20)
|
or al,mask $S2O_OBFUL ; Ensure output buffer marked as full
or al,mask $S2O_GATE ; Enable A20
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
A20ENA_ISA endp ; End A20ENA_ISA procedure
NPPROC A20ENA_XMS -- A20 Enable for XMS Drivers
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 enable for XMS drivers
On exit:
AH = XMS function code to enable A20
|
mov ah,@XMS_LCLENA ; Enable A20
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
A20ENA_XMS endp ; End A20ENA_XMS procedure
NPPROC GATEA20 -- Enable Address Line A20
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
Enable address line A20.
Different systems require different techniques. Here we
differentiate MC systems from non-MC systems only.
On exit:
CF = 0 if all went well
= 1 if we couldn't enable A20
|
push bx ; Save register
lea bx,ACTA20_ENA ; CS:BX ==> enable A20 actions
jmp short ACTA20_COM ; Join common code
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
GATEA20 endp ; End GATEA20 procedure
NPPROC A20DIS_MC -- A20 Disable for MC Systems
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 disable for Micro Channel systems
On entry:
AL = @PS2_A port value
On exit:
AL = (updated to disable A20)
|
and al,not (mask $PS2_GATE) ; Disable A20
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
A20DIS_MC endp ; End A20DIS_MC procedure
NPPROC A20DIS_ISA -- A20 Disable for ISA
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 disable for ISA
On entry:
AL = output port byte
On exit:
AL = (updated to disable A20)
|
or al,mask $S2O_OBFUL ; Ensure output buffer marked as full
and al,not (mask $S2O_GATE) ; Disable A20 gate
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
A20DIS_ISA endp ; End A20DIS_ISA procedure
NPPROC A20DIS_XMS -- A20 Disable for XMS Drivers
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 disable for XMS drivers
On exit:
AH = XMS function code to enable A20
|
mov ah,@XMS_LCLDIS ; Disable A20
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
A20DIS_XMS endp ; End A20DIS_XMS procedure
NPPROC DEGATEA20 -- Disable Address Line A20
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
Disable address line A20.
Different systems require different techniques. Here we
differentiate MC systems from non-MC systems only.
On exit:
CF = 0 if all went well
= 1 if we couldn't disable A20
|
push bx ; Save register
lea bx,ACTA20_DIS ; CS:BX ==> disable A20 actions
jmp short ACTA20_COM ; Join common code
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
DEGATEA20 endp ; End DEGATEA20 procedure
NPPROC ACTA20_COM -- A20 Enable/Disable Common Routine
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
A20 enable/disable common routine
Different systems require different techniques. Here we
differentiate MC systems from non-MC systems only.
On entry:
BX pushed onto stack
CS:BX ==> enable/disable action structure
|
push ax ; Save register
clc ; Assume all goes well
lahf ; Load AH with flags
pushf ; Save flags
cli ; Disallow interrupts
cmp XMSDRV_VEC,0 ; Is there an XMS driver?
jz short ACTA20_COM_NOXMS ; Not this time
call PGROUP:[bx].ACTA20_XMS ; Call common XMS action
call XMSDRV_VEC ; Request XMS service
jmp short ACTA20_COM_EXIT ; Join common exit code
ACTA20_COM_NOXMS:
test LCL_FLAG,@LCL_MC ; Izit an MC-compatible machine?
jz short ACTA20_COM_XMC ; Not this time
in al,@PS2_A ; Get system control port A
call PGROUP:[bx].ACTA20_MC ; Call common MC action
out @PS2_A,al ; Tell the system about it
jmp short ACTA20_COM_EXIT ; Join common exit code
ACTA20_COM_XMC:
; Write the output port byte
REGSAVE <ax> ; Save for a moment
; First, clear any pending scan code from the output buffer
; This might lose a keystroke
call WAITOBUF_CLR ; Wait for the output buffer to clear
mov ah,@S2C_ROUT ; Read output port byte command
call PPI_S2C_K2S ; Send AH to 8042, return with AL = response
jc short ACTA20_COM_ERR0 ; Jump if error (note CF=1)
call PGROUP:[bx].ACTA20_ISA ; Call common ISA action
mov ah,@S2C_WOUT ; Write output port byte
call PPI_S2C_S2K ; Write command AH, data AL to 8042
jc short ACTA20_COM_ERR0 ; Jump if error (note CF=1)
call PULSE8042 ; Pulse the 8042 to ensure A20 toggle done
; Return with CF significant
ACTA20_COM_ERR0:
pushf ; Save previous flags
; Last, enable the keyboard
mov ah,@S2C_ENA ; Enable the keyboard
call PPI_S2C ; Send command AH to 8042
; Ignore error return
popf ; Restore previous flags
ACTA20_COM_ERR1:
REGREST <ax> ; Restore
ACTA20_COM_ERR:
adc ah,0 ; Set CF in AH image of flags as necessary
ACTA20_COM_EXIT:
popf ; Restore flags
sahf ; Store AH into flags
pop ax ; Restore
pop bx ; Restore
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
ACTA20_COM endp ; End ACTA20_COM procedure
NPPROC PPI_S2C -- PPI System to Controller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
PPI System to Controller.
Send a command to the controller (8042).
Note that it's the caller's responsibility to ensure that
the 8042 output buffer is clear.
1. Wait for the input buffer to clear to avoid overrun.
2. Send the command in AH to the keyboard controller port 64h.
There is no acknowledgement of this command.
On entry:
AH = command
IF = 0
On exit:
CF = 1 if keyboard controller not responding
= 0 otherwise
|
call WAITIBUF_CLR ; Wait for input buffer to clear
jc short @F ; Error, controller not reading data (note CF=1)
xchg al,ah ; Swap to put command in AL
out @8042_ST,al ; Send the command
xchg al,ah ; Restore
@@:
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PPI_S2C endp ; End PPI_S2C procedure
NPPROC PPI_S2C_K2S -- PPI System to Controller, Keyboard to System
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
PPI System to Controller, Keyboard to System
Send a command to the controller (8042), wait for a response.
Note that it's the caller's responsibility to ensure that
the 8042 output buffer is clear.
1. Send the command to the 8042.
2. Wait for the output buffer to fill.
3. Read the response.
Note that resend does not occur with the controller (8042)
(although it can with the keyboard (6805)).
On entry:
AH = S2C command
IF = 0
On exit:
CF = 0 if all went OK
= 1 otherwise
AL = byte read (if CF=0)
|
call PPI_S2C ; Send command AH to 8042
jc short @F ; Jump if something went wrong (note CF=1)
call PPI_K2S ; Wait for a response, returned in AL
; Return with CF significant
@@:
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PPI_S2C_K2S endp ; End PPI_S2C_K2S procedure
NPPROC PPI_S2C_S2K -- PPI System to Controller, System to Keyboard
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
PPI System to Controller, System to Keyboard.
Note that it's the caller's responsibility to ensure that
the 8042 output buffer is clear.
1. Send the command to the 8042.
2. Send the data to the 8042.
On entry:
AH = S2C command
AL = byte to send
IF = 0
On exit:
CF = 0 if all went OK
= 1 otherwise
|
call PPI_S2C ; Send command AH to 8042
jc short PPI_S2C_S2K_EXIT ; Jump if something went wrong (note CF=1)
out @8255_A,al ; Send data AL to 8042
PPI_S2C_S2K_EXIT:
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PPI_S2C_S2K endp ; End PPI_S2C_S2K procedure
NPPROC PPI_K2S -- PPI Keyboard to System
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
PPI Keyboard to System.
Wait for a response from the keyboard or its controller.
On entry:
IF = 0
On exit:
CF = 1 if no response
= 0 otherwise
AL = response if CF=0
|
call WAITOBUF_SET ; Wait for the output buffer to fill
jc short @F ; Jump if no timely response (note CF=1)
in al,@8255_A ; Read in the code
@@:
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PPI_K2S endp ; End PPI_K2S procedure
NPPROC PPI_S2K -- PPI System to Keyboard
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
PPI System to Keyboard.
Send command to keyboard.
1. Wait for the input buffer to clear to avoid overrun.
2. Send the command in AH to the keyboard port 60h.
There is no acknowledgement of this command.
On entry:
AH = command to send
IF = 0
On exit:
CF = 1 if timeout
= 0 otherwise
AL = keyboard response if CF=0
|
call WAITIBUF_CLR ; Wait for input buffer to clear
jc short @F ; Error, controller not reading data (note CF=1)
xchg al,ah ; Swap to put command in AL
out @8255_A,al ; Issue the command
xchg al,ah ; Restore
@@:
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PPI_S2K endp ; End PPI_S2K procedure
NPPROC PPI_S2K_K2S -- PPI System to Keyboard, Keyboard to System
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
PPI System to Keyboard, Keyboard to System.
Send command to keyboard (6805), wait for its response.
Note that it's the caller's responsibility to ensure that
the 6805 output buffer is clear.
1. Send the command to the 6805.
2. Wait for the output buffer to fill.
3. Read the response.
4. Check for resend.
On entry:
AH = command to send
IF = 0
On exit:
CF = 1 if timeout
= 0 otherwise
AL = keyboard response if CF=0
|
push cx ; Save for a moment
mov cx,6 ; # retries of resend (arbitrary value)
PPI_S2K_K2S_AGAIN:
call PPI_S2K ; Send command AH to 6805
jc short PPI_S2K_K2S_EXIT ; Jump if something went wrong (note CF=1)
call PPI_K2S ; Wait for a response, returned in AL
jc short PPI_S2K_K2S_EXIT ; Jump if something went wrong (note CF=1)
cmp al,@K2S_RESEND ; Izit a resend?
clc ; In case not
jne short PPI_S2K_K2S_EXIT ; Jump if not (note CF=0)
loop PPI_S2K_K2S_AGAIN ; Jump if more retries
stc ; Indicate something went wrong
PPI_S2K_K2S_EXIT:
pop cx ; Restore
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PPI_S2K_K2S endp ; End PPI_S2K_K2S procedure
NPPROC WAITIBUF_CLR -- Wait For The Input Buffer To Clear
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
Wait for the one-byte input buffer to clear.
On entry:
IF = 0
On exit:
CF = 0 if buffer empty
= 1 otherwise
|
REGSAVE <ax,cx> ; Save registers
mov ah,6 ; Outer loop counter (arbitrary value)
xor cx,cx ; Inner loop counter (arbitrary value)
WAITIBUF_CLR1:
in al,@8042_ST ; Get status from keyboard
and al,mask $INPFULL ; Check Input Buffer Full flag
loopnz WAITIBUF_CLR1 ; Last char not read as yet
jz short WAITIBUF_CLR_EXIT ; Jump if buffer clear (note CF=0)
dec ah ; One fewer time
jnz short WAITIBUF_CLR1 ; Go around again
stc ; Indicate something went wrong
WAITIBUF_CLR_EXIT:
REGREST <cx,ax> ; Restore
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
WAITIBUF_CLR endp ; End WAITIBUF_CLR procedure
NPPROC WAITOBUF_CLR -- Wait For The Output Buffer To Clear
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
Wait for the one-byte output buffer to clear.
On entry:
IF = 0
|
push ax ; Save for a moment
WAITOBUF_CLR1:
in al,@8042_ST ; Get status from keyboard
and al,mask $OUTFULL ; Check Output Buffer Full flag
jz short WAITOBUF_CLR_EXIT ; Jump if buffer clear before
jmp short $+2 ; I/O delay
jmp short $+2 ; I/O delay
jmp short $+2 ; I/O delay
in al,@8255_A ; Purge the character
jmp short $+2 ; I/O delay
jmp short $+2 ; I/O delay
;;;;;;;; jmp short $+2 ; I/O delay
jmp short WAITOBUF_CLR1 ; Go around again
WAITOBUF_CLR_EXIT:
pop ax ; Restore
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
WAITOBUF_CLR endp ; End WAITOBUF_CLR procedure
NPPROC WAITOBUF_SET -- Wait for Output Buffer Full
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
Wait for the output buffer to fill.
On entry:
IF = 0
On exit:
CF = 1 if no response
= 0 otherwise
|
REGSAVE <ax,cx> ; Save registers
; Wait for a response
mov ah,6 ; Outer loop counter (arbitrary value)
xor cx,cx ; Inner loop counter (arbitrary value)
WAITOBUF_SET1:
in al,@8042_ST ; Get status from keyboard
and al,mask $OUTFULL ; Check Output Buffer Full flag
loopz WAITOBUF_SET1 ; Jump if no response as yet
jnz short WAITOBUF_SET_EXIT ; Join common exit code (note CF=0)
dec ah ; One fewer time
jnz short WAITOBUF_SET1 ; Jump if more tries available
stc ; Indicate something went wrong
WAITOBUF_SET_EXIT:
REGREST <cx,ax> ; Restore
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
WAITOBUF_SET endp ; End WAITOBUF_SET procedure
NPPROC PULSE8042 -- Pulse 8042
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
COMMENT|
Pulse the 8042 to ensure the last command has been accepted.
Typically (if needed at all), this is necssary after toggling A20
on an ISA bus machine.
|
; Pulse the controller to ensure the last 8042 command has been processed
push ax ; Save for a moment
mov ah,@S2C_RESET ; Ensure in a stable state
call PPI_S2C ; Send command AH to 8042
pop ax ; Restore
; Return with CF significant
PULSE8042_EXIT:
ret ; Return to caller
assume ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
PULSE8042 endp ; End PULSE8042 procedure
CODE ends ; End CODE segment
MEND ; End 386ID2 module